package com.hwl.trade.controller;

import com.github.wxpay.sdk.WXPayUtil;
import com.hwl.commonutils.result.RespBean;
import com.hwl.commonutils.result.ResultCodeEnum;
import com.hwl.trade.pojo.Order;
import com.hwl.trade.service.OrderService;
import com.hwl.trade.service.WeixinPayService;
import com.hwl.trade.util.StreamUtils;
import com.hwl.trade.util.WeixinPayProperties;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Api(tags = "微信支付")
@RestController
@RequestMapping("/api/order")
public class ApiWeixinPayController {

    @Resource
    private WeixinPayService weixinPayService;
    @Resource
    private WeixinPayProperties weixinPayProperties;
    @Resource
    private OrderService orderService;

    @ApiOperation("统一下单的接口调用")
    @GetMapping("auth/createNative/{orderNo}")
    public RespBean createNative(@PathVariable String orderNo, HttpServletRequest request) {
        String remoteAddr = request.getRemoteAddr();
        return RespBean.ok().data(weixinPayService.createNative(orderNo, remoteAddr));
    }

    //这个方法这里没有用上，只是跟着老师一起做的，是对微信的回调接收
    @ApiOperation("对微信的回调方法")
    @PostMapping("weixinPay/weixinNotify")
    public String wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("========================>");
        ServletInputStream inputStream = request.getInputStream();
        String notifyXml = StreamUtils.inputStream2String(inputStream, "utf-8");
        log.info("\n notifyXml = \n " + notifyXml);

        //验签：验证签名是否正确
        if (WXPayUtil.isSignatureValid(notifyXml, weixinPayProperties.getPartnerKey())) {

            //解析返回结果
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyXml);

            //判断支付是否成功
            if ("SUCCESS".equals(notifyMap.get("result_code"))) {

                //金额校验
                String totalFee = notifyMap.get("total_fee"); //支付结果返回的订单金额
                String outTradeNo = notifyMap.get("out_trade_no");//订单号
                Order order = orderService.getOrderByOrderNo(outTradeNo);//查询本地订单

                //校验返回的订单金额是否与商户侧的订单金额一致
                if (order != null && order.getTotalFee().intValue() == Integer.parseInt(totalFee)) {

                    //接口调用的幂等性：无论接口被调用多少次，最后所影响的结果都是一致的
                    if (order.getStatus() == 0) {
                        //更新订单状态
                        orderService.updateOrderStatus(notifyMap);
                    }

                    //支付成功：给微信发送我已接收通知的响应
                    //创建响应对象
                    Map<String, String> returnMap = new HashMap<>();
                    returnMap.put("return_code", "SUCCESS");
                    returnMap.put("return_msg", "OK");
                    String returnXml = WXPayUtil.mapToXml(returnMap);
                    response.setContentType("text/xml");
                    log.info("支付成功，通知已处理");
                    return returnXml;
                }
            }
        }

        //创建响应对象：微信接收到校验失败的结果后，会反复的调用当前回调函数
        Map<String, String> returnMap = new HashMap<>();
        returnMap.put("return_code", "FAIL");
        returnMap.put("return_msg", "");
        String returnXml = WXPayUtil.mapToXml(returnMap);
        response.setContentType("text/xml");
        log.info("校验失败，非微信返回的通知！");
        return returnXml;
    }

    //前端的定时任务
    @ApiOperation("向微信发起请求查询订单支付状态")
    @GetMapping("auth/queryPayStatus/{orderNo}")
    public RespBean queryPayStatus(@PathVariable String orderNo) {
        Map<String, String> map = weixinPayService.queryPayStatus(orderNo);

        if (map != null && weixinPayProperties.getAppId().equals(map.get("appid"))) {
            if ("SUCCESS".equals(map.get("trade_state"))) {
                //添加记录到支付表，更新订单状态
                orderService.updateOrderStatus(map);
                return RespBean.ok().message("支付成功！即将为您跳转到课程页面~");
            }
        }
        log.debug("{}订单支付进行中~", orderNo);
        return RespBean.setResult(ResultCodeEnum.PAY_RUN);
    }

}
